<?php

namespace app\controller;

use app\BaseController;
use app\service\WXBizDataCrypt;
use think\facade\Db;
use think\facade\Config;
use think\facade\Cache;

class Member extends BaseController
{
    /**
     * 统一微信登录接口：处理code、手机号、头像、昵称
     */
    public function unifiedWechatLogin()
    {
        $code = $this->request->param('code', '');
        $phoneEncryptedData = $this->request->param('phoneEncryptedData', '');
        $phoneIv = $this->request->param('phoneIv', '');
        $avatarUrl = $this->request->param('avatarUrl') ?: $this->request->domain() . '/static/avatar_default.png';
        $nickName = $this->request->param('nickName');


        if (empty($code) || empty($phoneEncryptedData) || empty($phoneIv)) {
            return json(['code' => 400, 'msg' => '参数不完整']);
        }
        try {
            // 1. 通过code获取openid和session_key
            $wechatRes = $this->getOpenidByCode($code);
            if (!isset($wechatRes['openid']) || !isset($wechatRes['session_key'])) {
                return json(['code' => 400, 'msg' => '获取微信OpenID或SessionKey失败']);
            }
            $openid = $wechatRes['openid'];
            $sessionKey = $wechatRes['session_key'];

            // 2. 解密手机号
            $phoneNumber = $this->decryptPhoneNumber($phoneEncryptedData, $phoneIv, $sessionKey);
            if (!$phoneNumber) {
                return json(['code' => 500, 'msg' => '手机号解密失败']);
            }
            // 如果昵称为空，使用手机号隐藏中间几位数作为默认昵称
            if (empty($nickName) && !empty($phoneNumber)) {
                $nickName = substr($phoneNumber, 0, 3) . '****' . substr($phoneNumber, -4);
            }


            // 3. 查找或创建会员，并更新头像、昵称和手机号
            $member = $this->findOrCreateMember($openid, $avatarUrl, $nickName);
            if ($member) {
                // 更新手机号
                Db::name('sysmemberinfo')
                    ->where('id', $member['id'])
                    ->update(['MemberPhone' => $phoneNumber]);

                // 重新获取更新后的会员信息，确保返回最新数据
                $member = Db::name('sysmemberinfo')->where('id', $member['id'])->find();

                // 生成登录token
                $token = $this->generateToken($member['id']);

                return json(
                    [
                        'code' => 200,
                        'data' => [
                            'token' => $token,
                            'member_info' => $member
                        ],
                        'msg' => '登录成功'
                    ]
                );
            } else {
                return json(['code' => 500, 'msg' => '登录失败']);
            }
        } catch (\Exception $e) {
            return json(['code' => 500, 'msg' => '系统错误：' . $e->getMessage()]);
        }
    }

    /**
     * 通过code获取openid和session_key
     */
    private function getOpenidByCode($code)
    {
        $appId = Config::get('applet.wechat.app_id');
        $appSecret = Config::get('applet.wechat.app_secret');
        $apiUrl = Config::get('applet.wechat.api_url');

        if (empty($appId) || empty($appSecret)) {
            throw new \Exception('微信小程序配置不完整');
        }

        $url = $apiUrl . '/sns/jscode2session';
        $params = [
            'appid' => $appId,
            'secret' => $appSecret,
            'js_code' => $code,
            'grant_type' => 'authorization_code'
        ];

        $response = $this->httpGet($url . '?' . http_build_query($params));
        $data = json_decode($response, true);

        return $data; // 返回包含openid和session_key的数组
    }

    /**
     * 查找或创建会员
     */
    private function findOrCreateMember($openid, $avatarUrl = '', $nickName = '')
    {
        // 先查找是否已存在该openid的会员
        $member = Db::name('sysmemberinfo')
            ->where('open_id', $openid)
            ->find();

        $updateData = [];
        if (!empty($avatarUrl)) {
            $updateData['MemberAvatar'] = $avatarUrl;
        }
        if (!empty($nickName)) {
            $updateData['MemberNickName'] = $nickName;
        }

        if ($member) {
            // 如果存在，更新头像和昵称
            if (!empty($updateData)) {
                Db::name('sysmemberinfo')
                    ->where('id', $member['id'])
                    ->update($updateData);
                $member = array_merge($member, $updateData); // 更新返回的会员信息
            }
            return $member;
        }

        // 如果不存在，创建新会员
        $memberData = [
            'MemberCardNom' => $this->generateMemberCardNumber(),
            'open_id' => $openid,
            'CreateTime' => date('Y-m-d H:i:s'),
            'Memberbrithday' => date('Y-m-d'),
            'MemberAmount' => 0,
            'MemberPoints' => 0,
            'MemberAccumulatedPoints' => 0
        ];
        $memberData = array_merge($memberData, $updateData);

        $memberId = Db::name('sysmemberinfo')->insertGetId($memberData);

        if ($memberId) {
            $memberData['id'] = $memberId;
            return $memberData;
        }

        return false;
    }

    /**
     * 解密微信小程序手机号
     */
    private function decryptPhoneNumber($encryptedData, $iv, $sessionKey)
    {

        $appId = Config::get('applet.wechat.app_id');
        $pc = new WXBizDataCrypt($appId, $sessionKey);
        $errCode = $pc->decryptData($encryptedData, $iv, $data);

        if ($errCode == 0) {
            $data = json_decode($data, true);
            return $data['phoneNumber'] ?? false;
        }

        return false;
    }

    /**
     * 生成会员卡号
     */
    private function generateMemberCardNumber()
    {
        $timestamp = date('YmdHis');
        $random = sprintf('%04d', mt_rand(0, 9999));

        return $timestamp . $random;
    }

    /**
     * 生成登录token
     */
    private function generateToken($memberId)
    {
        $token = md5($memberId . time() . mt_rand(1000, 9999));

        // 将token存储到缓存中，有效期2小时
        Cache::set('member_token_' . $token, $memberId, 7200);

        return $token;
    }

    /**
     * 验证token
     */
    public function verifyToken()
    {
        $token = $this->request->header('token', '');

        if (empty($token)) {
            return json(['code' => 401, 'msg' => 'token不能为空']);
        }

        $memberId = Cache::get('member_token_' . $token);

        if (!$memberId) {
            return json(['code' => 401, 'msg' => 'token无效或已过期']);
        }

        // 获取会员信息
        $member = Db::name('sysmemberinfo')
            ->where('id', $memberId)
            ->find();

        if (!$member) {
            return json(['code' => 404, 'msg' => '会员不存在']);
        }

        return json(
            [
                'code' => 200,
                'data' => [
                    'member_info' => $member
                ],
                'msg' => '验证成功'
            ]
        );
    }

    /**
     * 获取会员信息
     */
    public function getMemberInfo()
    {
        $memberId = $this->getMemberIdFromToken();

        if (!$memberId) {
            return json(['code' => 401, 'msg' => '请先登录']);
        }

        try {
            $member = Db::name('sysmemberinfo')
                ->where('id', $memberId)
                ->find();

            if (!$member) {
                return json(['code' => 404, 'msg' => '会员不存在']);
            }

            // 获取客户实名信息
            $customerInfo = Db::name('customerinfo')
                ->where('member_id', $memberId)
                ->find();

            return json(
                [
                    'code' => 200,
                    'data' => [
                        'member_info' => $member,
                        'customer_info' => $customerInfo
                    ],
                    'msg' => '获取成功'
                ]
            );
        } catch (\Exception $e) {
            return json(['code' => 500, 'msg' => '系统错误：' . $e->getMessage()]);
        }
    }

    /**
     * 从token获取会员ID
     */
    private function getMemberIdFromToken()
    {
        $token = $this->request->header('token', '');

        if (empty($token)) {
            return false;
        }

        return Cache::get('member_token_' . $token);
    }

    /**
     * HTTP GET请求
     */
    private function httpGet($url)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_TIMEOUT, 10);

        $response = curl_exec($ch);
        curl_close($ch);

        return $response;
    }
}
